import React, { useState } from 'react';
import { Upload, Button, Spin, message, Image, Card } from 'antd';
import type { GetProp, UploadFile, UploadProps } from 'antd';
import jsQR from 'jsqr';

type FileType = Parameters<GetProp<UploadProps, 'beforeUpload'>>[0];

const QrCodeReader: React.FC = () => {
    const [fileList, setFileList] = useState<UploadFile[]>([]);
    const [qrResult, setQrResult] = useState<string>('');
    const [loading, setLoading] = useState<boolean>(false);
    const [previewImage, setPreviewImage] = useState<string>('');

    const onChange: UploadProps['onChange'] = ({ fileList: newFileList }) => {
        setFileList(newFileList);
    };

    const beforeUpload = async (file: FileType) => {
        setLoading(true);
        try {
            // 1. 读取文件为DataURL
            const imageUrl = await readFileAsDataURL(file);
            setPreviewImage(imageUrl); // 显示预览图

            // 2. 解析二维码
            const qrContent = await decodeQrCode(imageUrl);

            if (qrContent) {
                setQrResult(qrContent);
                message.success('二维码解析成功！');
            } else {
                setQrResult('');
                message.warning('未检测到二维码');
            }

            return false; // 阻止自动上传
        } catch (error) {
            message.error('二维码解析失败');
            console.error(error);
            return false;
        } finally {
            setLoading(false);
        }
    };

    // 读取文件为DataURL
    const readFileAsDataURL = (file: File): Promise<string> => {
        return new Promise((resolve, reject) => {
            const reader = new FileReader();
            reader.onload = () => resolve(reader.result as string);
            reader.onerror = reject;
            reader.readAsDataURL(file);
        });
    };

const decodeQrCode = async (imageSrc: string): Promise<string | null> => {
  return new Promise((resolve) => {
    const img = new window.Image();
    img.crossOrigin = "anonymous"; // 处理跨域问题
    
    img.onload = () => {
      const canvas = document.createElement('canvas');
      canvas.width = img.width;
      canvas.height = img.height;
      const ctx = canvas.getContext('2d');
      
      ctx?.drawImage(img, 0, 0);
      const imageData = ctx?.getImageData(0, 0, img.width, img.height);
      
      if (imageData) {
        const code = jsQR(imageData.data, imageData.width, imageData.height);
        const rawData = code?.data || null;
        
        try {
          // 1. 尝试解析是否为 URL 编码（例如 "%7B" → "{")
          const potentialURIDecoded = rawData && decodeURIComponent(rawData);
          
          // 2. 尝试解析是否为 JSON（例如解码后 '{"trId":"..."}'）
          const potentialJSON = potentialURIDecoded && tryParseJSON(potentialURIDecoded);
          
          // 3. 尝试解析是否为 Base64（例如 'eyJ0cklkIjoi...' → '{"trId":"..."}'）
          const potentialBase64Decoded = rawData && tryDecodeBase64(rawData);
          const potentialBase64JSON = potentialBase64Decoded && tryParseJSON(potentialBase64Decoded);

          // 返回最可能的解码内容
          const decodedResult = potentialBase64JSON || potentialJSON || potentialURIDecoded || rawData;
          resolve(decodedResult || null);
        } catch (error) {
          console.error("解码失败:", error);
          resolve(rawData); // 返回原始数据
        }
      } else {
        resolve(null);
      }
    };
    
    img.onerror = () => {
      console.error("图片加载失败");
      resolve(null);
    };
    
    img.src = imageSrc;
  });
};

// 辅助函数：尝试解析 JSON
function tryParseJSON(str: string): any | null {
  try {
    return JSON.parse(str);
  } catch (e) {
    return null;
  }
}

// 辅助函数：尝试解码 Base64
function tryDecodeBase64(str: string): string | null {
  try {
    if (/^[A-Za-z0-9+/=]+$/.test(str)) {
      return decodeURIComponent(atob(str)); // Base64 → URL编码 → 普通文本
    }
    return null;
  } catch (e) {
    return null;
  }
}




    const onPreview = async (file: UploadFile) => {
        let src = file.url as string;
        if (!src && file.originFileObj) {
            src = await readFileAsDataURL(file.originFileObj);
        }
        setPreviewImage(src || '');
    };

    const handleOpenLink = () => {
        if (qrResult.startsWith('http')) {
            window.open(qrResult, '_blank', 'noopener,noreferrer');
        }
    };

    return (
        <div style={{ padding: 24 }}>
            <Card title="二维码解析工具" bordered={false}>
                <Upload
                    listType="picture-card"
                    fileList={fileList}
                    onChange={onChange}
                    beforeUpload={beforeUpload}
                    onPreview={onPreview}
                    accept="image/*"
                    maxCount={1}  // 限制只能上传1个文件
                >
                    {fileList.length < 1 && '+ 上传图片'}
                </Upload>

                <div style={{ marginTop: 24 }}>
                    {loading && <Spin tip="正在解析二维码..." />}

                    {qrResult && (
                        <Card type="inner" title="解析结果">
                            <div style={{
                                padding: 12,
                                backgroundColor: '#f5f5f5',
                                borderRadius: 4,
                                wordBreak: 'break-word',
                                fontFamily: 'monospace'
                            }}>
                                {qrResult}
                            </div>

                            {qrResult.startsWith('http') && (
                                <Button
                                    type="link"
                                    onClick={handleOpenLink}
                                    style={{ marginTop: 8 }}
                                >
                                    打开链接
                                </Button>
                            )}
                        </Card>
                    )}

                    {previewImage && (
                        <Image
                            width={200}
                            style={{ display: 'none' }}
                            src={previewImage}
                            preview={{
                                visible: !!previewImage,
                                onVisibleChange: (visible) => !visible && setPreviewImage(''),
                            }}
                        />
                    )}
                </div>
            </Card>
        </div>
    );
};

export default QrCodeReader;
